home *** CD-ROM | disk | FTP | other *** search
/ STraTOS 1997 April & May / STraTOS 1 - 1997 April & May.iso / CD01 / INTERNET / SITES / LITTLE / P3SRC.ZIP / ATARI / OBJECTS.C < prev    next >
Encoding:
C/C++ Source or Header  |  1996-06-16  |  14.9 KB  |  955 lines

  1. /****************************************************************************
  2. *                objects.c
  3. *
  4. *  This module implements the methods for objects and composite objects.
  5. *
  6. *  from Persistence of Vision(tm) Ray Tracer
  7. *  Copyright 1996 Persistence of Vision Team
  8. *---------------------------------------------------------------------------
  9. *  NOTICE: This source code file is provided so that users may experiment
  10. *  with enhancements to POV-Ray and to port the software to platforms other
  11. *  than those supported by the POV-Ray Team.  There are strict rules under
  12. *  which you are permitted to use this file.  The rules are in the file
  13. *  named POVLEGAL.DOC which should be distributed with this file. If
  14. *  POVLEGAL.DOC is not available or for more info please contact the POV-Ray
  15. *  Team Coordinator by leaving a message in CompuServe's Graphics Developer's
  16. *  Forum.  The latest version of POV-Ray may be found there as well.
  17. *
  18. * This program is based on the popular DKB raytracer version 2.12.
  19. * DKBTrace was originally written by David K. Buck.
  20. * DKBTrace Ver 2.0-2.12 were written by David K. Buck & Aaron A. Collins.
  21. *
  22. *****************************************************************************/
  23.  
  24. #include "frame.h"
  25. #include "povray.h"
  26. #include "vector.h"
  27. #include "povproto.h"
  28. #include "objects.h"
  29. #include "texture.h"
  30. #include "halos.h"
  31.  
  32.  
  33.  
  34. /*****************************************************************************
  35. * Local preprocessor defines
  36. ******************************************************************************/
  37.  
  38.  
  39.  
  40. /*****************************************************************************
  41. * Local typedefs
  42. ******************************************************************************/
  43.  
  44.  
  45.  
  46. /*****************************************************************************
  47. * Local variables
  48. ******************************************************************************/
  49.  
  50. unsigned int Number_of_istacks;
  51. unsigned int Max_Intersections;
  52. ISTACK *free_istack;
  53.  
  54.  
  55.  
  56. /*****************************************************************************
  57. * Static functions
  58. ******************************************************************************/
  59.  
  60. static OBJECT *Copy_Bound_Clip PARAMS((OBJECT *Old));
  61. static void create_istack PARAMS((void));
  62.  
  63.  
  64.  
  65. /*****************************************************************************
  66. *
  67. * FUNCTION
  68. *
  69. *   Intersection
  70. *
  71. * INPUT
  72. *   
  73. * OUTPUT
  74. *   
  75. * RETURNS
  76. *   
  77. * AUTHOR
  78. *
  79. *   POV-Ray Team
  80. *   
  81. * DESCRIPTION
  82. *
  83. *   -
  84. *
  85. * CHANGES
  86. *
  87. *   -
  88. *
  89. ******************************************************************************/
  90.  
  91. int Intersection (Ray_Intersection, Object, Ray)
  92. INTERSECTION *Ray_Intersection;
  93. OBJECT *Object;
  94. RAY *Ray;
  95. {
  96.   ISTACK *Depth_Stack;
  97.   INTERSECTION *Local;
  98.   DBL Closest = HUGE_VAL;
  99.  
  100.   if (Object == NULL)
  101.   {
  102.     return (FALSE);
  103.   }
  104.  
  105.   if (!Ray_In_Bound (Ray,Object->Bound))
  106.   {
  107.     return (FALSE);
  108.   }
  109.  
  110.   Depth_Stack = open_istack ();
  111.  
  112.   if (All_Intersections (Object, Ray, Depth_Stack))
  113.   {
  114.     while ((Local = pop_entry(Depth_Stack)) != NULL)
  115.     {
  116.       if (Local->Depth < Closest)
  117.       {
  118.         *Ray_Intersection = *Local;
  119.  
  120.         Closest = Local->Depth;
  121.       }
  122.     }
  123.  
  124.     close_istack (Depth_Stack);
  125.  
  126.     return (TRUE);
  127.   }
  128.   else
  129.   {
  130.     close_istack (Depth_Stack);
  131.  
  132.     return (FALSE);
  133.   }
  134. }
  135.  
  136.  
  137.  
  138. /*****************************************************************************
  139. *
  140. * FUNCTION
  141. *
  142. *   Inside_Object
  143. *
  144. * INPUT
  145. *   
  146. * OUTPUT
  147. *   
  148. * RETURNS
  149. *   
  150. * AUTHOR
  151. *
  152. *   POV-Ray Team
  153. *   
  154. * DESCRIPTION
  155. *
  156. *   -
  157. *
  158. * CHANGES
  159. *
  160. *   -
  161. *
  162. ******************************************************************************/
  163.  
  164. int Inside_Object (IPoint, Object)
  165. VECTOR IPoint;
  166. OBJECT *Object;
  167. {
  168.   OBJECT *Sib;
  169.  
  170.   for (Sib = Object->Clip; Sib != NULL; Sib = Sib->Sibling)
  171.   {
  172.     if (!Inside_Object(IPoint, Sib))
  173.     {
  174.       return(FALSE);
  175.     }
  176.   }
  177.  
  178.   return (Inside(IPoint,Object));
  179. }
  180.  
  181.  
  182.  
  183. /*****************************************************************************
  184. *
  185. * FUNCTION
  186. *
  187. *   Ray_In_Bound
  188. *
  189. * INPUT
  190. *   
  191. * OUTPUT
  192. *   
  193. * RETURNS
  194. *   
  195. * AUTHOR
  196. *
  197. *   POV-Ray Team
  198. *   
  199. * DESCRIPTION
  200. *
  201. *   -
  202. *
  203. * CHANGES
  204. *
  205. *   -
  206. *
  207. ******************************************************************************/
  208.  
  209. int Ray_In_Bound (Ray, Bounding_Object)
  210. RAY *Ray;
  211. OBJECT *Bounding_Object;
  212. {
  213.   OBJECT *Bound;
  214.   INTERSECTION Local;
  215.  
  216.   for (Bound = Bounding_Object; Bound != NULL; Bound = Bound->Sibling)
  217.   {
  218.     Increase_Counter(stats[Bounding_Region_Tests]);
  219.  
  220.     if (!Intersection (&Local, Bound, Ray))
  221.     {
  222.       if (!Inside_Object(Ray->Initial, Bound))
  223.       {
  224.         return (FALSE);
  225.       }
  226.     }
  227.  
  228.     Increase_Counter(stats[Bounding_Region_Tests_Succeeded]);
  229.   }
  230.  
  231.   return (TRUE);
  232. }
  233.  
  234.  
  235.  
  236. /*****************************************************************************
  237. *
  238. * FUNCTION
  239. *
  240. *   Point_In_Clip
  241. *
  242. * INPUT
  243. *   
  244. * OUTPUT
  245. *   
  246. * RETURNS
  247. *   
  248. * AUTHOR
  249. *
  250. *   POV-Ray Team
  251. *   
  252. * DESCRIPTION
  253. *
  254. *   -
  255. *
  256. * CHANGES
  257. *
  258. *   -
  259. *
  260. ******************************************************************************/
  261.  
  262. int Point_In_Clip (IPoint, Clip)
  263. VECTOR IPoint;
  264. OBJECT *Clip;
  265. {
  266.   OBJECT *Local_Clip;
  267.  
  268.   for (Local_Clip = Clip; Local_Clip != NULL; Local_Clip = Local_Clip->Sibling)
  269.   {
  270.     Increase_Counter(stats[Clipping_Region_Tests]);
  271.  
  272.     if (!Inside_Object(IPoint, Local_Clip))
  273.     {
  274.       return (FALSE);
  275.     }
  276.  
  277.     Increase_Counter(stats[Clipping_Region_Tests_Succeeded]);
  278.   }
  279.  
  280.   return (TRUE);
  281. }
  282.  
  283.  
  284.  
  285. /*****************************************************************************
  286. *
  287. * FUNCTION
  288. *
  289. *   Translate_Object
  290. *
  291. * INPUT
  292. *   
  293. * OUTPUT
  294. *   
  295. * RETURNS
  296. *   
  297. * AUTHOR
  298. *
  299. *   POV-Ray Team
  300. *   
  301. * DESCRIPTION
  302. *
  303. *   -
  304. *
  305. * CHANGES
  306. *
  307. *   -
  308. *
  309. ******************************************************************************/
  310.  
  311. void Translate_Object (Object, Vector, Trans)
  312. OBJECT *Object;
  313. VECTOR Vector;
  314. TRANSFORM *Trans;
  315. {
  316.   OBJECT *Sib;
  317.  
  318.   if (Object == NULL)
  319.   {
  320.     return;
  321.   }
  322.  
  323.   for (Sib = Object->Bound; Sib != NULL; Sib = Sib->Sibling)
  324.   {
  325.     Translate_Object (Sib, Vector, Trans);
  326.   }
  327.  
  328.   if (Object->Clip != Object->Bound)
  329.   {
  330.     for (Sib = Object->Clip; Sib != NULL; Sib = Sib->Sibling)
  331.     {
  332.       Translate_Object (Sib, Vector, Trans);
  333.     }
  334.   }
  335.  
  336.   Translate_Textures (Object->Texture, Trans);
  337.  
  338.   Translate_Halo_Container (Object->Texture, Trans);
  339.  
  340.   Translate (Object, Vector, Trans);
  341. }
  342.  
  343.  
  344.  
  345. /*****************************************************************************
  346. *
  347. * FUNCTION
  348. *
  349. *   Rotate_Object
  350. *
  351. * INPUT
  352. *
  353. * OUTPUT
  354. *   
  355. * RETURNS
  356. *   
  357. * AUTHOR
  358. *
  359. *   POV-Ray Team
  360. *
  361. * DESCRIPTION
  362. *
  363. *   -
  364. *
  365. * CHANGES
  366. *
  367. *   -
  368. *
  369. ******************************************************************************/
  370.  
  371. void Rotate_Object (Object, Vector, Trans)
  372. OBJECT *Object;
  373. VECTOR Vector;
  374. TRANSFORM *Trans;
  375. {
  376.   OBJECT *Sib;
  377.  
  378.   if (Object == NULL)
  379.   {
  380.     return;
  381.   }
  382.  
  383.   for (Sib = Object->Bound; Sib != NULL; Sib = Sib->Sibling)
  384.   {
  385.     Rotate_Object (Sib, Vector, Trans);
  386.   }
  387.  
  388.   if (Object->Clip != Object->Bound)
  389.   {
  390.     for (Sib = Object->Clip; Sib != NULL; Sib = Sib->Sibling)
  391.     {
  392.       Rotate_Object (Sib, Vector, Trans);
  393.     }
  394.   }
  395.  
  396.   Rotate_Textures (Object->Texture, Trans);
  397.  
  398.   Rotate_Halo_Container (Object->Texture, Trans);
  399.  
  400.   Rotate (Object, Vector, Trans);
  401. }
  402.  
  403.  
  404.  
  405. /*****************************************************************************
  406. *
  407. * FUNCTION
  408. *
  409. *   Scale_Object
  410. *
  411. * INPUT
  412. *
  413. * OUTPUT
  414. *   
  415. * RETURNS
  416. *   
  417. * AUTHOR
  418. *
  419. *   POV-Ray Team
  420. *   
  421. * DESCRIPTION
  422. *
  423. *   -
  424. *
  425. * CHANGES
  426. *
  427. *   -
  428. *
  429. ******************************************************************************/
  430.  
  431. void Scale_Object (Object, Vector, Trans)
  432. OBJECT *Object;
  433. VECTOR Vector;
  434. TRANSFORM *Trans;
  435. {
  436.   OBJECT *Sib;
  437.  
  438.   if (Object == NULL)
  439.   {
  440.     return;
  441.   }
  442.  
  443.   for (Sib = Object->Bound; Sib != NULL; Sib = Sib->Sibling)
  444.   {
  445.     Scale_Object (Sib, Vector, Trans);
  446.   }
  447.  
  448.   if (Object->Clip != Object->Bound)
  449.   {
  450.     for (Sib = Object->Clip; Sib != NULL; Sib = Sib->Sibling)
  451.     {
  452.       Scale_Object (Sib, Vector, Trans);
  453.     }
  454.   }
  455.  
  456.   Scale_Textures (Object->Texture, Trans);
  457.  
  458.   Scale_Halo_Container (Object->Texture, Trans);
  459.  
  460.   Scale (Object, Vector, Trans);
  461. }
  462.  
  463.  
  464.  
  465. /*****************************************************************************
  466. *
  467. * FUNCTION
  468. *
  469. *   Transform_Object
  470. *
  471. * INPUT
  472. *   
  473. * OUTPUT
  474. *   
  475. * RETURNS
  476. *   
  477. * AUTHOR
  478. *
  479. *   POV-Ray Team
  480. *   
  481. * DESCRIPTION
  482. *
  483. *   -
  484. *
  485. * CHANGES
  486. *
  487. *   -
  488. *
  489. ******************************************************************************/
  490.  
  491. void Transform_Object (Object, Trans)
  492. OBJECT *Object;
  493. TRANSFORM *Trans;
  494. {
  495.   OBJECT *Sib;
  496.  
  497.   if (Object == NULL)
  498.   {
  499.     return;
  500.   }
  501.  
  502.   for (Sib = Object->Bound; Sib != NULL; Sib = Sib->Sibling)
  503.   {
  504.     Transform_Object (Sib, Trans);
  505.   }
  506.  
  507.   if (Object->Clip != Object->Bound)
  508.   {
  509.     for (Sib = Object->Clip; Sib != NULL; Sib = Sib->Sibling)
  510.     {
  511.       Transform_Object (Sib, Trans);
  512.     }
  513.   }
  514.  
  515.   Transform_Textures (Object->Texture, Trans);
  516.  
  517.   Transform_Halo_Container (Object->Texture, Trans);
  518.  
  519.   Transform (Object,Trans);
  520. }
  521.  
  522.  
  523.  
  524. /*****************************************************************************
  525. *
  526. * FUNCTION
  527. *
  528. *   Invert_Object
  529. *
  530. * INPUT
  531. *   
  532. * OUTPUT
  533. *   
  534. * RETURNS
  535. *   
  536. * AUTHOR
  537. *
  538. *   POV-Ray Team
  539. *   
  540. * DESCRIPTION
  541. *
  542. *   -
  543. *
  544. * CHANGES
  545. *
  546. *   -
  547. *
  548. ******************************************************************************/
  549.  
  550. void Invert_Object (Object)
  551. OBJECT *Object;
  552. {
  553.   if (Object == NULL)
  554.   {
  555.     return;
  556.   }
  557.  
  558.   Invert (Object);
  559. }
  560.  
  561.  
  562.  
  563. /*****************************************************************************
  564. *
  565. * FUNCTION
  566. *
  567. *   Copy_Bound_Clip
  568. *
  569. * INPUT
  570. *   
  571. * OUTPUT
  572. *   
  573. * RETURNS
  574. *   
  575. * AUTHOR
  576. *
  577. *   POV-Ray Team
  578. *   
  579. * DESCRIPTION
  580. *
  581. *   -
  582. *
  583. * CHANGES
  584. *
  585. *   -
  586. *
  587. ******************************************************************************/
  588.  
  589. static OBJECT *Copy_Bound_Clip (Old)
  590. OBJECT *Old;
  591. {
  592.   OBJECT *Current, *New, *Prev, *First;
  593.  
  594.   First = Prev = NULL;
  595.  
  596.   for (Current = Old; Current != NULL; Current = Current->Sibling)
  597.   {
  598.     New = Copy_Object (Current);
  599.  
  600.     if (First == NULL)
  601.     {
  602.       First = New;
  603.     }
  604.  
  605.     if (Prev != NULL)
  606.     {
  607.       Prev->Sibling = New;
  608.     }
  609.  
  610.     Prev = New;
  611.   }
  612.  
  613.   return (First);
  614. }
  615.  
  616.  
  617.  
  618. /*****************************************************************************
  619. *
  620. * FUNCTION
  621. *
  622. *   Copy_Object
  623. *
  624. * INPUT
  625. *   
  626. * OUTPUT
  627. *   
  628. * RETURNS
  629. *   
  630. * AUTHOR
  631. *
  632. *   POV-Ray Team
  633. *   
  634. * DESCRIPTION
  635. *
  636. *   -
  637. *
  638. * CHANGES
  639. *
  640. *   -
  641. *
  642. ******************************************************************************/
  643.  
  644. OBJECT *Copy_Object (Old)
  645. OBJECT *Old;
  646. {
  647.   OBJECT *New;
  648.  
  649.   if (Old == NULL)
  650.   {
  651.     return (NULL);
  652.   }
  653.  
  654.   New = Copy (Old);
  655.   COOPERATE_0
  656.  
  657.  /*
  658.   * The following copying of OBJECT_FIELDS is redundant if Copy
  659.   * did *New = *Old but we cannot assume it did. It is safe for
  660.   * Copy to do *New = *Old but it should not otherwise
  661.   * touch OBJECT_FIELDS.
  662.   */
  663.  
  664.   New->Methods = Old->Methods;
  665.   New->Type    = Old->Type;
  666.   New->Sibling = Old->Sibling;
  667.   New->Texture = Old->Texture;
  668.   New->Bound   = Old->Bound;
  669.   New->Clip    = Old->Clip;
  670.   New->BBox    = Old->BBox;
  671.   New->Flags   = Old->Flags;
  672.  
  673.   New->Sibling = NULL;  /* Important */
  674.  
  675.   New->Texture = Copy_Textures (Old->Texture);
  676.  
  677.   New->Bound   = Copy_Bound_Clip (Old->Bound);
  678.  
  679.   if (Old->Bound != Old->Clip)
  680.   {
  681.     New->Clip  = Copy_Bound_Clip (Old->Clip);
  682.   }
  683.   else
  684.   {
  685.     New->Clip  = New->Bound;
  686.   }
  687.  
  688.   return (New);
  689. }
  690.  
  691.  
  692.  
  693. /*****************************************************************************
  694. *
  695. * FUNCTION
  696. *
  697. *   Destroy_Object
  698. *
  699. * INPUT
  700. *
  701. * OUTPUT
  702. *
  703. * RETURNS
  704. *
  705. * AUTHOR
  706. *
  707. *   POV-Ray Team
  708. *
  709. * DESCRIPTION
  710. *
  711. *   -
  712. *
  713. * CHANGES
  714. *
  715. *   -
  716. *
  717. ******************************************************************************/
  718.  
  719. void Destroy_Object (Object)
  720. OBJECT *Object;
  721. {
  722.   OBJECT *Sib;
  723.  
  724.   while (Object != NULL)
  725.   {
  726.     Destroy_Textures (Object->Texture);
  727.  
  728.     Destroy_Object (Object->Bound);
  729.  
  730.     if (Object->Bound != Object->Clip)
  731.     {
  732.       Destroy_Object (Object->Clip);
  733.     }
  734.  
  735.     Sib = Object->Sibling;
  736.  
  737.     Destroy(Object);
  738.  
  739.     Object = Sib;
  740.   }
  741. }
  742.  
  743.  
  744.  
  745. /*****************************************************************************
  746. *
  747. * FUNCTION
  748. *
  749. *   create_istack
  750. *
  751. * INPUT
  752. *
  753. * OUTPUT
  754. *
  755. * RETURNS
  756. *
  757. * AUTHOR
  758. *
  759. *   POV-Ray Team
  760. *
  761. * DESCRIPTION
  762. *
  763. *   -
  764. *
  765. * CHANGES
  766. *
  767. *   -
  768. *
  769. ******************************************************************************/
  770.  
  771. static void create_istack()
  772. {
  773.   ISTACK *New;
  774.  
  775.   New = (ISTACK *)POV_MALLOC(sizeof (ISTACK), "istack");
  776.  
  777.   New->next = free_istack;
  778.  
  779.   free_istack = New;
  780.  
  781.   New->istack = (INTERSECTION *)POV_MALLOC(Max_Intersections * sizeof (INTERSECTION), "istack entries");
  782.  
  783.   Number_of_istacks++;
  784. }
  785.  
  786.  
  787.  
  788.  
  789. /*****************************************************************************
  790. *
  791. * FUNCTION
  792. *
  793. *   Destroy_IStacks
  794. *
  795. * INPUT
  796. *
  797. * OUTPUT
  798. *
  799. * RETURNS
  800. *
  801. * AUTHOR
  802. *
  803. *   POV-Ray Team
  804. *
  805. * DESCRIPTION
  806. *
  807. *   -
  808. *
  809. * CHANGES
  810. *
  811. *   -
  812. *
  813. ******************************************************************************/
  814.  
  815. void Destroy_IStacks()
  816. {
  817.   ISTACK *istk, *temp;
  818.  
  819.   istk = free_istack;
  820.  
  821.   while (istk != NULL)
  822.   {
  823.     temp = istk;
  824.  
  825.     istk = istk->next;
  826.  
  827.     POV_FREE (temp->istack);
  828.  
  829.     POV_FREE (temp);
  830.   }
  831.  
  832.   free_istack = NULL;
  833. }
  834.  
  835.  
  836.  
  837. /*****************************************************************************
  838. *
  839. * FUNCTION
  840. *
  841. *   open_sstack
  842. *
  843. * INPUT
  844. *
  845. * OUTPUT
  846. *
  847. * RETURNS
  848. *
  849. * AUTHOR
  850. *
  851. *   POV-Ray Team
  852. *
  853. * DESCRIPTION
  854. *
  855. *   -
  856. *
  857. * CHANGES
  858. *
  859. *   -
  860. *
  861. ******************************************************************************/
  862.  
  863. ISTACK *open_istack()
  864. {
  865.   ISTACK *istk;
  866.  
  867.   if (free_istack == NULL)
  868.   {
  869.     create_istack ();
  870.   }
  871.  
  872.   istk = free_istack;
  873.  
  874.   free_istack = istk->next;
  875.  
  876.   istk->top_entry = 0;
  877.  
  878.   return (istk);
  879. }
  880.  
  881.  
  882.  
  883. /*****************************************************************************
  884. *
  885. * FUNCTION
  886. *
  887. *   close_istack
  888. *
  889. * INPUT
  890. *
  891. * OUTPUT
  892. *
  893. * RETURNS
  894. *
  895. * AUTHOR
  896. *
  897. *   POV-Ray Team
  898. *
  899. * DESCRIPTION
  900. *
  901. *   -
  902. *
  903. * CHANGES
  904. *
  905. *   -
  906. *
  907. ******************************************************************************/
  908.  
  909. void close_istack (istk)
  910. ISTACK *istk;
  911. {
  912.   istk->next = free_istack;
  913.  
  914.   free_istack = istk;
  915. }
  916.  
  917.  
  918.  
  919. /*****************************************************************************
  920. *
  921. * FUNCTION
  922. *
  923. *   incstack
  924. *
  925. * INPUT
  926. *
  927. * OUTPUT
  928. *
  929. * RETURNS
  930. *
  931. * AUTHOR
  932. *
  933. *   POV-Ray Team
  934. *
  935. * DESCRIPTION
  936. *
  937. *   -
  938. *
  939. * CHANGES
  940. *
  941. *   -
  942. *
  943. ******************************************************************************/
  944.  
  945. void incstack(istk)
  946. ISTACK *istk;
  947. {
  948.   if (++istk->top_entry >= Max_Intersections)
  949.   {
  950.     istk->top_entry--;
  951.  
  952.     Increase_Counter(stats[Istack_overflows]);
  953.   }
  954. }
  955.